package datasource

import (
	"fmt"
	"github.com/gomodule/redigo/redis"
	"log"
	"lottery/conf"
	"sync"
	"time"
	//"github.com/go-redis/redis/v8"
)

// 创建redis 互斥锁
var rdsLock sync.Mutex

// 定义包级别的全局变量接收实例
var cacheInstance *RedisConn

// 连接对象
type RedisConn struct {
	pool      *redis.Pool
	showDebug bool // 是否需要debug
}

// debug： 自己实现debug 函数
func (rds *RedisConn) Do(commandName string,
	args ...interface{}) (reply interface{}, err error) {
	conn := rds.pool.Get() // 从池中获取链接
	defer conn.Close()     // 将链接的资源 返回到池中

	t1 := time.Now().UnixNano()
	reply, err = conn.Do(commandName, args...) // 执行指令
	if err != nil {
		e := conn.Err() // 当连接不可用时，返回非空值，必须关闭连接。
		log.Println("rdshelper.Do", err, e)
	}
	t2 := time.Now().UnixNano()
	if rds.showDebug {
		fmt.Printf("[redis] [info] [%dus]cmd=%s, err = %s, args=%v, reply=%s\n",
			(t2-t1)/1000, commandName, err, args, reply)
	}
	return reply, err
}

// 设置debug： 函数式编程
func (rds *RedisConn) ShowDebug(b bool) {
	rds.showDebug = b
}

// 得到唯一的redis缓存（池）实例
func InstanceCache() *RedisConn {
	if cacheInstance != nil {
		return cacheInstance
	}
	rdsLock.Lock()
	defer rdsLock.Unlock()

	if cacheInstance != nil {
		return cacheInstance
	}
	return NewCache()
}

// 重新实例化: 创建redis 连接池
func NewCache() *RedisConn {
	pool := redis.Pool{
		Dial: func() (redis.Conn, error) {
			c, err := redis.Dial("tcp", fmt.Sprintf("%s:%d", conf.RdsCache.Host, conf.RdsCache.Port))
			if err != nil {
				log.Fatal("rdshelper.NewCache Dial error ", err)
				return nil, err
			}
			return c, nil
		},
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			if time.Since(t) < time.Minute {
				return nil
			}
			_, err := c.Do("PING")
			return err
		},
		MaxIdle:         10000,
		MaxActive:       10000,
		IdleTimeout:     0,
		Wait:            false,
		MaxConnLifetime: 0, // 关闭比这个 持续时长更长的链接。为 0 默认不关闭。
	}
	instance := &RedisConn{
		pool: &pool,
	}
	cacheInstance = instance
	//cacheInstance.ShowDebug(true)
	cacheInstance.ShowDebug(false)
	return cacheInstance
}
